/**
 * Copyright (c) 2016-2023, Michael Yang 杨福海 (fuhai999@gmail.com).
 * <p>
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jpress.module.article.directive;

import com.jfinal.aop.Inject;
import com.jfinal.template.Env;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.Scope;
import io.jboot.utils.DateUtil;
import io.jboot.utils.StrUtil;
import io.jboot.web.directive.annotation.JFinalDirective;
import io.jboot.web.directive.base.JbootDirectiveBase;
import io.jpress.SiteContext;
import io.jpress.commons.utils.SqlUtils;
import io.jpress.module.article.model.Article;
import io.jpress.module.article.service.ArticleService;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Set;


/**
 * @author Michael Yang 杨福海 （fuhai999@gmail.com）
 * @version V1.0
 */
@JFinalDirective("articleViewsCountStatistics")
public class ArticleViewsCountStatisticsDirective extends JbootDirectiveBase {


    @Inject
    private ArticleService articleService;


    @Override
    public void onRender(Env env, Scope scope, Writer writer) {

        String withSite = getParaToString("withSite", scope);
        int count = getParaToInt("count", scope, 10);

        boolean queryToday = getParaToBool("queryToday", scope, false);
        boolean queryWeek = getParaToBool("queryWeek", scope, false);
        boolean queryMonth = getParaToBool("queryMonth", scope, false);
        boolean queryQuarter = getParaToBool("queryQuarter", scope, false);
        boolean queryYear = getParaToBool("queryYear", scope, false);
        boolean queryTotal = getParaToBool("queryTotal", scope, false);


        String sql = "select a.*,b.visit_count from article a left join " +
                "(select count(*) visit_count,data_id from utm where data_type = 1 and created > ? group by data_id) b " +
                "on a.id = b.data_id " +
                "where a.status = 'normal' " +
                getSiteCond(withSite) +
                "order by visit_count desc,id desc " +
                "limit " + count;

        if (queryToday) {
            List<Article> todayArticles = articleService.findListBySql(sql, DateUtil.getStartOfToday());
            scope.setLocal("todayArticles", todayArticles);
        }


        if (queryWeek) {
            List<Article> thisWeekArticles = articleService.findListBySql(sql, DateUtil.getStartOfThisWeek());
            scope.setLocal("weekArticles", thisWeekArticles);
        }

        if (queryMonth) {
            List<Article> thisMonthArticles = articleService.findListBySql(sql, DateUtil.getStartOfThisMonth());
            scope.setLocal("monthArticles", thisMonthArticles);
        }

        if (queryQuarter) {
            List<Article> thisQuarterCondArticles = articleService.findListBySql(sql, DateUtil.getStartOfThisQuarter());
            scope.setLocal("quarterArticles", thisQuarterCondArticles);
        }


        if (queryYear) {
            List<Article> thisYearCondArticles = articleService.findListBySql(sql, DateUtil.getStartOfThisYear());
            scope.setLocal("yearArticles", thisYearCondArticles);
        }


        if (queryTotal) {
            String totalSql = "select a.*,b.visit_count from article a left join " +
                    "(select count(*) visit_count,data_id from utm where data_type = 1 and group by data_id) b " +
                    "on a.id = b.data_id " +
                    "where a.status = 'normal' " +
                    getSiteCond(withSite) +
                    "order by visit_count desc,id desc " +
                    "limit " + count;
            List<Article> totalArticles = articleService.findListBySql(totalSql);
            scope.setLocal("totalArticles", totalArticles);
        }

        renderBody(env, scope, writer);
    }

    @NotNull
    private String getSiteCond(String withSite) {
        if (StrUtil.isBlank(withSite)) {
            return "and a.site_id = " + SiteContext.getSiteId() + " ";
        }

        withSite = withSite.trim();

        if ("*".equals(withSite) || "all".equals(withSite)) {
            return " ";
        } else {
            Set<String> strings = StrUtil.splitToSetByComma(withSite);
            return "and a.site_id in " + SqlUtils.buildInSqlPara(strings.toArray()) + " ";
        }
    }


    @Override
    public boolean hasEnd() {
        return true;
    }
}
